#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <syslog.h>
#include <sys/param.h>

#define DEBUG_SAMPLE 
#define DAEM
#ifdef DAEM
#define OUT_PUT(format,args...) syslog(LOG_ERR,format,##args)
#else
#define OUT_PUT(format,args...) printf(format,##args)
#endif


struct wxt520_data
{
	int Dm;/*平均风向*/
	float Sm;/*平均风速*/
	float Ta;/*温度*/
	float Ua;/*相对湿度*/
	float Pa;/*气压*/
	float Rc;/*雨量累计mm*/
	float Hc;/*冰雹累计 hits/cm2h */
};

struct p_gdw_weath
{
	long mtype;
	float average_windspeed_10min;/*十分钟平均风速*/
	int average_winddirection_10min;/*十分钟平均风向*/
	float max_windspeed;
	float extreme_windspeed;
	float standard_windspeed;
	float air_temperature;
	float humidity;
	float air_pressure;
	float precipitation;
	float precipitation_intensity;
};
struct p_gdw_weath src_data;/*原始气象数据*/

int db_pos = 0;
struct wxt520_data db_per_m[64];/*一分钟数据保存*/
#define R0 "%*dR0,Dm=%dD,Sm=%fM,Ta=%fC,Ua=%fP,Pa=%fH,Rc=%fM,Hc=%fM\n"
#define R0_WXT(dat) dat.Dm,dat.Sm,dat.Ta,dat.Ua,dat.Pa,dat.Rc,dat.Hc
extern int open_serial(const char *serial_port);
void print(struct wxt520_data *dat);
void do_process(struct wxt520_data *dat);

char *dev_name =NULL;
int baud = 9600;
#define LOCKFILENAME "/var/run/sample.pid"
int main(int argc,char **argv)
{
	int fd = 0;
	int err = 0;
	int n = 0,i=0;
	char buf[2][100];
	char tmp[100];
	char *pos =NULL;
	char *str =NULL;
	fd_set rfd;

	struct wxt520_data wxt;
	struct timeval timeout;
	timeout.tv_sec = 5;
	timeout.tv_usec = 0;

	if (getuid())
	{
		printf("this program must be run in root\n");
		return -1;
	}
	/*检查程序唯一性*/
	if(alreadly_running(LOCKFILENAME))
	{
		printf("%s is running\n",argv[0]);
		return -1;
	}
#ifdef DAEM
	daemonize("sample-log");

	if(alreadly_running(LOCKFILENAME))
	{
		printf("%s is running\n",argv[0]);
		return -1;
	}
#endif
	//if (create_msgque("/dev/ttyUSB0")< 0)
	if (create_msgque("/dev/ttySPI0")< 0)
		return -1;
	//fd = open_serial("/dev/ttyUSB0");
	fd = open_serial("/dev/ttySPI0");
	if (fd < 0)
	{
		//printf("open serial error\n");
		OUT_PUT("open serial error\n");
		return -1;
	}
	printf("run to this....\n");
	perror("THIS");
	memset(buf,0,200);
	pos = buf[0];
	for (;;)
	{
		FD_ZERO(&rfd);
		FD_SET(fd, &rfd);
		err = -1;
		sleep(1);
		err = select(fd + 1, &rfd, NULL, NULL, &timeout);
		switch (err)
		{
			case -1:
				perror("select");
				break;
			default:
			{
				if (FD_ISSET(fd,&rfd))
				{
					memset(tmp,0,100);
					n = read(fd,tmp,99);/*从串口读30个字符*/
					if (n<0)
						continue;
					for (i =0; i< n; i++)
					{
						if (tmp[i] != '\n')
						{
							if (((pos > (&buf[0][100] -20)) &&(pos < &buf[1][0])) ||
							    (pos > (&buf[1][0] +80)) )
							{
								pos = buf[0];
								memset(buf,0,200);
							}
							
							*pos++=tmp[i];
						}
						else
						{
							*pos++='\n';
							*pos++='\0';
							pos = buf[pos < &buf[1][0]? 1:0];
							memset(pos,0,100);
						}
					}
					//OUT_PUT("tmp:%s\nbuf:%s\n",tmp,pos < &buf[1][0]?buf[1]:buf[0]);
					str =(pos < &buf[1][0]?buf[1]:buf[0]);
#ifdef DEBUG_SAMPLE
					//printf("buf:%s\n",str);
					OUT_PUT("buf:%s\n",str);
#endif
					if (!sscanf(str,R0,R0_WXT(&wxt)))/*注意这里的&wxt*/
						continue;
#ifdef DEBUG_SAMPLE
					//print(&wxt);
#endif
					do_process(&wxt);
				}
			}
		}
	}
	close(fd);
	return 0;
}

void print(struct wxt520_data *dat)
{
	OUT_PUT("recv----------------------\n");
	OUT_PUT("平均风向:\t%d\n",dat->Dm);
	OUT_PUT("平均风速:\t%f\n",dat->Sm);
	OUT_PUT("温度:\t\t%f\n",dat->Ta);
	OUT_PUT("相对湿度:\t%f\n",dat->Ua);
	OUT_PUT("气压:\t\t%f\n",dat->Pa);
	OUT_PUT("雨量累计:\t%f\n",dat->Rc);
	OUT_PUT("冰雹累计:\t%f\n",dat->Hc);
}
void print_src()
{
	OUT_PUT("\t\t原始数据报文...\n");
	OUT_PUT("10分钟平均风速:\t%f\n",src_data.average_windspeed_10min);
	OUT_PUT("10分钟平均风向:\t%d\n",src_data.average_winddirection_10min);
	OUT_PUT("最大风速:\t%f\n",src_data.max_windspeed);
	OUT_PUT("极大风速:\t%f\n",src_data.extreme_windspeed);
	OUT_PUT("标准风速:\t%f\n",src_data.standard_windspeed);
	OUT_PUT("气温:\t\t%f\n",src_data.air_temperature);
	OUT_PUT("湿度:\t\t%f\n",src_data.humidity);
	OUT_PUT("气压:\t\t%f\n",src_data.air_pressure);
	OUT_PUT("降雨量:\t\t%f\n",src_data.precipitation);
	OUT_PUT("降水强度:\t%f\n",src_data.precipitation_intensity);
}
int get_data_notwind()
{
	/*采样数率为每分钟6次，去掉最大值，最小值，计算平均数*/
	int i;
	float resT=0.0,resU=0.0,resP=0.0;
	float maxT,maxU,maxP,minT,minU,minP;
	/*取10s,20s,30s,40s,50s,60s处的温度*/
	maxT=minT=db_per_m[9].Ta;
	maxU=minU=db_per_m[9].Ua;
	maxP=minP=db_per_m[9].Pa;
	for (i = 0;i<6;i++)
	{
		resT += db_per_m[9+10*i].Ta;
		resU += db_per_m[9+10*i].Ua;
		resP += db_per_m[9+10*i].Pa;
		
		if (maxT < db_per_m[9+10*i].Ta)
			maxT = db_per_m[9+10*i].Ta;
		if (minT > db_per_m[9+10*i].Ta)
			minT = db_per_m[9+10*i].Ta;

		if (maxU < db_per_m[9+10*i].Ua)
			maxU = db_per_m[9+10*i].Ua;
		if (minU > db_per_m[9+10*i].Ua)
			minU = db_per_m[9+10*i].Ua;

		if (maxP < db_per_m[9+10*i].Pa)
			maxP = db_per_m[9+10*i].Pa;
		if (minP > db_per_m[9+10*i].Pa)
			minP = db_per_m[9+10*i].Pa;
	}
	src_data.air_temperature= (resT-minT-maxT)/4;
	src_data.humidity= (resU-minU-maxU)/4;
	src_data.air_pressure= (resP-minP-maxP)/4;
	src_data.precipitation =db_per_m[59].Rc;/*降雨量*/
	src_data.precipitation_intensity = \
		db_per_m[59].Rc-db_per_m[0].Rc;
	return 0;
}
/*三秒钟的平均值为瞬时值，两分钟采样一次风的瞬时值*/

void do_process(struct wxt520_data *dat)
{
	int i = 0;
	float max_wind;
	db_per_m[db_pos++].Dm = dat->Dm;
	db_per_m[db_pos].Sm = dat->Sm;
	db_per_m[db_pos].Ta = dat->Ta;
	db_per_m[db_pos].Ua = dat->Ua;
	db_per_m[db_pos].Pa = dat->Pa;
	db_per_m[db_pos].Rc = dat->Rc;
	db_per_m[db_pos].Hc = dat->Hc;
	if (db_pos > 60)/*封装数据报*/
	{
		get_data_notwind();
		/*挑选最大风速*/
		max_wind = db_per_m[0].Sm;
		src_data.average_winddirection_10min =db_per_m[0].Dm;
		src_data.average_windspeed_10min=db_per_m[0].Sm;
		for (i = 0;i<60;i++)
		{
			if (max_wind <db_per_m[i].Sm)
				max_wind = db_per_m[i].Sm;
			
			src_data.average_windspeed_10min+=(db_per_m[i].Sm -src_data.average_windspeed_10min)/(i+1);
		
			if (db_per_m[i].Dm-src_data.average_winddirection_10min > 180)
					src_data.average_winddirection_10min += (db_per_m[i].Dm -src_data.average_winddirection_10min-360)/(i+1);
			if (db_per_m[i].Dm-src_data.average_winddirection_10min < -180)
				src_data.average_winddirection_10min += (db_per_m[i].Dm -src_data.average_winddirection_10min+360)/(i+1);

			if (src_data.average_winddirection_10min>360)
				src_data.average_winddirection_10min -=360;
			if (src_data.average_winddirection_10min<0)
				src_data.average_winddirection_10min +=360;
		}
		/*原始数据中最大风速等于极大风速*/
		src_data.max_windspeed=src_data.extreme_windspeed=max_wind;
		//src_data.average_windspeed_10min=(src_data.average_windspeed_10min - max_wind)/58;
		//src_data.average_winddirection_10min /=60;
		db_pos = 0;
#ifdef DEBUG_SAMPLE
		print_src();
#endif
		src_data.mtype = 1987;
		send_msgque((unsigned char *)&src_data,sizeof(struct p_gdw_weath));
	}
}